package org.kaer.election.fragment;

import android.app.Dialog;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.gson.Gson;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.kaer.election.R;
import org.kaer.election.bean.Candidate;
import org.kaer.election.bean.SelectedElection;
import org.kaer.election.trade.ExampleClient;
import org.kaer.election.ui.ElectionActivity;
import org.kaer.election.utils.BitmapUtils;
import org.kaer.election.utils.ByteUtils;
import org.kaer.election.utils.CommonUtil;
import org.kaer.election.utils.JSONKeys;
import org.kaer.election.utils.LogUtils;
import org.kaer.election.utils.NetworkUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

import android_serialport_api.SerialPortInterface;
import android_serialport_api.sample.SerialPortReader;
import cn.com.aratek.idcard.IDCardReader;
import fynn.app.PromptDialog;

/**
 * Created by lizj on 2016/7/6.
 */
public class ReadIDFragment extends BaseFragment implements SerialPortInterface {
    private ImageView readIDCardIv;
    private IDCardReader mReader;
    private static final int DEVICE_OPEN = 0x10001;
    private static final int DEVICE_CLOSE = 0x10003;
    private static final int READ_ID = 0x10002;
    private SelectedElection election;
    private boolean readFlag;
    private SerialPortReader mSerialPortReader;
    private Gson mGson;

    public static ReadIDFragment newInstance(Bundle mBundle) {
        ReadIDFragment fragment = new ReadIDFragment();
        fragment.setArguments(mBundle);
        return fragment;
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_readidcard;
    }

    private Handler mHandler = new Handler() {

        public void handleMessage(android.os.Message msg) {

            switch (msg.what) {
                case DEVICE_OPEN:
                    if (msg.arg1 == IDCardReader.RESULT_OK) {
                        //readID();
                        mTimer.start();
                    } else {
                        Toast.makeText(mContext, R.string.id_card_reader_open_failed, Toast.LENGTH_SHORT)
                                .show();

                    }
                    break;
                case DEVICE_CLOSE:
                    //  delayTimer.start();
                    break;
                case READ_ID:
//                    LogUtils.i(ByteUtils.formatData((byte[]) msg.obj));
                    byte[] data = (byte[]) msg.obj;
                    if (data[2] == (byte) 0x90) {
                        if (data[3] == 0x00 || data[3] == 0x01) { /**0x00 身份证 0x01 M1卡*/
                            // 可以继续下一步操作
                            byte[] id = Arrays.copyOfRange(data, 4, data.length - 1);
                            String cardId = ByteUtils.byteToHexString(id);
                            Toast.makeText(mContext, "证件ID " + cardId, Toast.LENGTH_SHORT).show();
                            mBundle.putInt("election_id", election.electionId);
                            mBundle.putString(JSONKeys.Voter.CardId, cardId);
                            readFlag = false;
                            mHandler.removeCallbacks(r);
                            if (mTimer != null) {
                                mTimer.cancel();
                            }
                            new ReadRecordTask().execute(cardId, String.valueOf(election.electionId));
                        } else {
                            Toast.makeText(mContext, "请放置有效的身份证件", Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        Toast.makeText(mContext, "请将证件放到指定区域", Toast.LENGTH_SHORT).show();
                    }

                    break;
                default:
                    break;
            }
        }

        ;
    };

    // reopen the serialport every five minute
    private CountDownTimer mTimer = new CountDownTimer(1000 * 302 * 1, 1000 * 3) {

        @Override
        public void onTick(long millisUntilFinished) {
            // TODO Auto-generated method stub
            if (readFlag) {
                readID();
            }
        }

        @Override
        public void onFinish() {
            // TODO Auto-generated method stub
            LogUtils.e("Timer onFinish");
            try {
//                mHandler.removeCallbacks(r);
//                mSerialPortReader.closeSerailPort();
//                if (readFlag) {
//                    mSerialPortReader.openSerialPort(mContext);
//                    mTimer.start();
//                    readID();
//                }
                removeFragment();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (mExampleClient.getConnectState() != mExampleClient.STATE_CONNECTED) {
            removeFragment();
        }
    }

    @Override
    protected void initView(View view, Bundle savedInstanceState) {
        mBundle = getArguments();
        String data = mBundle.getString(JSONKeys.Voter.ElectionData);
        election = new Gson().fromJson(data, SelectedElection.class);

        readIDCardIv = (ImageView) findView(R.id.readIDCardIv);
        setMargins(readIDCardIv, 0, 200, 0, 0);
        readIDCardIv.setImageBitmap(BitmapUtils.scaleBitmap(mContext,
                BitmapFactory.decodeResource(getResources(), R.drawable.read_id_card),
               /* Math.pow(1.618 / (1 + 1.618), 2)*/0.6));

        if (election == null) {
            Toast.makeText(mContext, "没有获取到投票信息,请重新搜索", Toast.LENGTH_SHORT).show();
            removeFragment();
            return;
        }
        getHoldingActivity().initTitle(election.electionName);
        LogUtils.i("electionType =" + election.getElectionType());
        if (election.getElectionType() != 2 && election.getElectionType() != 1) {
            Toast.makeText(mContext, "选举类型错误,请重新搜索", Toast.LENGTH_SHORT).show();
            removeFragment();
            return;
        } else {
            //
            LogUtils.i("electionType 满足要求");
            mSerialPortReader = SerialPortReader.getInstance();
            mSerialPortReader.setSerialPortInterface(this);
            mSerialPortReader.openSerialPort(mContext);
            mReader = IDCardReader.getInstance();

        }
        mGson = new Gson();
    }


    @Override
    public void onStart() {
        // TODO Auto-generated method stub
        super.onStart();

    }

    @Override
    public void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        LogUtils.i("ReadIDFragment onResume");
        // IntentFilter dynamic_filter = new IntentFilter();
        // dynamic_filter.addAction(ElectionVoteApplication.DYNAMICACTIONREADIDCARDFORM);
        // // 添加动态广播的Action
        // registerReceiver(dynamicReceiver, dynamic_filter); // 注册自定义动态广播消息
        checkServer();

    }

    private void checkServer() {
        if (mExampleClient.getConnectState() != mExampleClient.STATE_CONNECTED|| !NetworkUtil.isAvailable(mContext)) {
            LogUtils.w("websocket_disconnected,back to searchServer");
            removeFragment();
        } else {
            openDevice();
        }
    }

    private void openDevice() {
        new Thread(new Runnable() {
            public void run() {
                if (mReader != null) {
                    readFlag = true;

                    int ret = mReader.powerOn();
                    if (ret != IDCardReader.RESULT_OK) {
                        ret = mReader.powerOn();
                    }
                    ret=0;
                    mHandler.obtainMessage(DEVICE_OPEN, ret, ret).sendToTarget();
                }
            }
        }).start();
    }

    private void closeDevice() {
        readFlag = false;
        if (mTimer != null) {
            mTimer.cancel();
        }
        mHandler.removeCallbacks(r);
        new Thread(new Runnable() {
            public void run() {
                if (mReader != null)
                    mReader.powerOff();
                mHandler.sendEmptyMessage(DEVICE_CLOSE);

            }
        }).start();
    }

    class ConnectServerTask extends AsyncTask<String, Integer, Integer> {
        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            if (mExampleClient.getConnectState() == mExampleClient.STATE_CONNECTED)
                mExampleClient.disconnectServer();
            showProgressDialog("正在连接服务器...", mContext);
        }

        @Override
        protected Integer doInBackground(String... params) {
            // TODO Auto-generated method stub
            int state = mExampleClient.connectServer(params[0], 6310, mContext); //// 连接websocket

            return state;
        }

        @Override
        protected void onPostExecute(Integer result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            dismissDialog();
            if (result == mExampleClient.STATE_CONNECTED) {
                Toast.makeText(mContext, "服务器已连接", Toast.LENGTH_SHORT).show();
                openDevice();
            } else {
                mHandler.postDelayed(r, 3000);
            }
        }
    }


    private void readID() {

        byte[] s = {(byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0x96, 0x69, 0x00, 0x03, 0x06, 0x01, 0x04};
        LogUtils.i("readID command" /*+ ByteUtils.formatData(s)*/);
        try {
            mSerialPortReader.write(s);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            mSerialPortReader.closeSerailPort();
            if (readFlag) {
                mSerialPortReader.openSerialPort(mContext);

            }

        }
//        try {
//            if (r != null && readFlag) {
//                mHandler.removeCallbacks(r);
//                mHandler.postDelayed(r, 3000);
//
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        // waitTimer.start();

    }

    private CountDownTimer waitTimer = new CountDownTimer(1000, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            LogUtils.i("waitTimer . finish ");
            closeDevice();
        }
    };
    private CountDownTimer delayTimer = new CountDownTimer(2000, 2000) {
        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            checkServer();
        }
    };
    Runnable r = new Runnable() {
        public void run() {
            if (mExampleClient.getConnectState() != mExampleClient.STATE_CONNECTED) {
                checkServer();
            } else if (readFlag)
                readID();
        }
    };

    @Override
    public void onDataReceived(byte[] buffer, int size) {
        // TODO Auto-generated method stub
        if (size > 0) {
            mHandler.obtainMessage(READ_ID, buffer).sendToTarget();
        }
    }

    @Override
    public void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        LogUtils.i("ReadIDFragment onPause");
//            if (mSerialPortReader != null) {
//                mSerialPortReader.closeSerailPort();
//            }
        readFlag = false;
        if (mTimer != null) {
            mTimer.cancel();
        }
        mHandler.removeCallbacks(r);
        new Thread(new Runnable() {
            public void run() {
                if (mReader != null)
                    mReader.powerOff();
            }
        }).start();
    }


    class ReadRecordTask extends AsyncTask<String, Integer, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showProgressDialog("数据检测中...");
        }

        @Override
        protected String doInBackground(String... params) {
            return mExampleClient.readRecord(params[0], params[1]);

        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            dismissDialog();
            if (TextUtils.isEmpty(result)) {
                Toast.makeText(mContext, "服务器繁忙", Toast.LENGTH_SHORT).show();
                return;
            }
            try {
                LogUtils.i(result);
                JSONObject retJson = new JSONObject(result);
                int retCode = CommonUtil.GetJsonIntValue(retJson, JSONKeys.Voter.ResultCode, -1);
                if (retCode == ExampleClient.Success) {
                    //解析出已选的信息
                    mBundle.putParcelableArrayList(JSONKeys.Voter.AlreadyVote, parseRecordList(result));
                    mBundle.remove(JSONKeys.Voter.ChooseList);
                    //   app.setInfoList(null);
                    // 职位投票
                    // 普选候选人
                    startActivity(ElectionActivity.class, mBundle);
                } else {
                    new PromptDialog.Builder(mContext).setViewStyle(PromptDialog.VIEW_STYLE_TITLEBAR_COLOR).setTitleBarColor(getResources().getColor(R.color.colorPrimaryDark)).setTitle("提示").setTitleSize(getResources().getDimension(R.dimen.textsize26)).setMessage(mExampleClient.getErrorMessage(retCode)).setMessageSize(getResources().getDimension(R.dimen.textsize24)).setButton1("确定", new PromptDialog.OnClickListener() {
                        @Override
                        public void onClick(Dialog dialog, int which) {
                            dialog.dismiss();
                            readFlag = true;
                            mTimer.start();
                        }
                    }).setButton1Size(getResources().getDimension(R.dimen.textsize24)).setCancelable(false)
                            .create().show();
//                    showPromptDialog(mExampleClient.getErrorMessage(retCode), new PromptDialog.OnClickListener() {
//                        @Override
//                        public void onClick(Dialog dialog, int which) {
//                            dialog.dismiss();
//                            readFlag = true;
//                            mTimer.start();
//                        }
//                    });

//                    Toast.makeText(mContext, mExampleClient.getErrorMessage(retCode), Toast.LENGTH_SHORT).show();

                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    private ArrayList<Candidate> parseRecordList(final String result) throws JSONException {
        ArrayList<Candidate> infoList = new ArrayList<>();
        if (!TextUtils.isEmpty(result)) {
            JSONObject object = new JSONObject(result);
            JSONArray array = object.getJSONArray(JSONKeys.Voter.RecordList);
            for (int i = 0; i < array.length(); i++) {
                Candidate info = mGson.fromJson(array.getJSONObject(i).toString(), Candidate.class);
                infoList.add(info);
            }
        }
        return infoList;
    }
}
